package com.bcinfo.iccard.busi.handler;

import java.util.Date;

import org.apache.commons.lang3.exception.ExceptionUtils;
import com.bcinfo.iccard.busi.AbstractBusinessHandler;
import com.bcinfo.iccard.busi.AccountLock;
import com.bcinfo.iccard.enums.Constants;
import com.bcinfo.iccard.exception.IccardException;
import com.bcinfo.iccard.model.ComboCardExpensiveRecordTemp;
import com.bcinfo.iccard.model.ComboCardSaleDetail;
import com.bcinfo.iccard.model.Pos;
import com.bcinfo.iccard.model.RechargeableCard;
import com.bcinfo.iccard.model.RechargeablecardExpensiveRecordTemp;
import com.solab.iso8583.IsoMessage;
import com.solab.iso8583.IsoType;
/**
 * 消费处理
 * @author wangguangchun
 *
 */
public class SaleDebitHandler extends AbstractBusinessHandler {

    @Override
	public void handleBusiness(IsoMessage req, IsoMessage resp)
			throws Exception {
		// TODO Auto-generated method stub
	    if(req==null ||resp==null){
            throw new IccardException("iso message req or resp is null,discard this request!");
        }
        if(_logger.isDebugEnabled()){
            _logger.debug("handleBusiness:"+req.toString());
        }
        RechargeableCard card=null;
        Pos pos=getPos(req);
        String qrCode=null;
        try
        {
            resp.copyFieldsFrom(req, 3,11,24,41,42);
            String tradeType=(String)req.getField(22).getValue();
            if(Constants.TradeType.qrCode.value.equals(tradeType)){
                //二维码消费
                String encryptQrCode=(String)req.getField(48).getValue();
                qrCode=parseQrCode(encryptQrCode);
                boolean isQrCodeOk=false;
                if(qrCode==null){
                    resp.setValue(39, Constants.ResponeCode.invalidCardNum.value, IsoType.ALPHA, 2);
                }else{
                    //判断控制锁中是否有
                    if(AccountLock.getInstance().contains(qrCode)){
                        //该二维码正在使用中
                        resp.setValue(39, Constants.ResponeCode.requestProgressing.value, IsoType.ALPHA, 2);
                    }else{
                        //放入控制锁
                        AccountLock.getInstance().put(qrCode, qrCode);
                        ComboCardSaleDetail detail= comboCardTradeService.loadByQrCode(qrCode);
                        long now=System.currentTimeMillis();
                        if(detail!= null && detail.getExtractStatus()!=1 && (now>detail.getComboCard().getBegintime().getTime()&& now<=detail.getComboCard().getEndtime().getTime())){
                            isQrCodeOk=true;
                        }
                        //二维码有效
                        if(isQrCodeOk){
                            ComboCardExpensiveRecordTemp temp=comboCardTradeService.loadyByMerQrCode(pos.getMerchantCode(), qrCode);
                            //为预交易状态或者已完成交易状态，则提示交易重复
                            if(temp!=null &&temp.getExpensiveStatus()<=1){
                                resp.setValue(39, Constants.ResponeCode.reEnterTrans.value, IsoType.ALPHA, 2);
                            }else{
                                //交易成功
                                temp=new ComboCardExpensiveRecordTemp();
                                temp.setSerialNumber(generateSerialNum());
                                ComboCardExpensiveRecordTemp t=comboCardTradeService.comboCardTrade(temp,pos,qrCode);
                                String serialNum=t.getSerialNumber();
                                resp.setValue(37,Constants.TradeType.qrCodeTrade.value+serialNum , IsoType.ALPHA, 12);
                                resp.setValue(39,Constants.ResponeCode.approval.value, IsoType.ALPHA, 2);
                            }
                        }else{
                            //二维码无效
                            resp.setValue(39, Constants.ResponeCode.invalidCardNum.value, IsoType.ALPHA, 2);
                        }
                     }
                 }
            }else{
                card=checkCardNo(req);
                //充值卡无效
                if(card==null){
                    _logger.error("invalid card Num,please check again!");
                    resp.setValue(39, Constants.ResponeCode.invalidCardNum.value, IsoType.ALPHA, 2);
                }else{
                    if(AccountLock.getInstance().contains(card.getRechargeableCardNum())){
                        //该卡正在使用中
                        resp.setValue(39, Constants.ResponeCode.requestProgressing.value, IsoType.ALPHA, 2);
                    }else{
                        //加入控制锁
                        AccountLock.getInstance().put(card.getRechargeableCardNum(),card.getRechargeableCardNum());
                        boolean isPin=false;
                        //有密码，则进行pinBlock校验
                        if(Constants.TradeType.cardWithPwd.value.equals(tradeType)||Constants.TradeType.manualWithPwd.value.equals(tradeType)){
                            byte[] pinBlockFromClient=(byte[])req.getField(52).getValue();
                            isPin=checkPin(pinBlockFromClient, pos.getPik(), card);
                            //测试，不校验pin
                        }else{
                            //无密码不进行pinBlock校验
                            isPin=true;
                            if(_logger.isDebugEnabled()){
                                _logger.debug("tradType:"+tradeType+", check pin skipped.");
                            }
                        }
                        if(isPin){
                            //消费
                            String amountStr=(String)req.getField(4).getValue();
                            long amount=parseBalance(amountStr);
                            if(amount==0 ||amount>1000000){
                                //金额不能为空
                                resp.setValue(39, Constants.ResponeCode.invalidAmount.value, IsoType.ALPHA, 2);
                            }else if((amount/100.00)>card.getRechargeableCardAccountTotal()){
                                //可用余额不足
                                resp.setValue(39, Constants.ResponeCode.exceedLimit.value, IsoType.ALPHA, 2);
                            }else{
                                RechargeablecardExpensiveRecordTemp temp=new RechargeablecardExpensiveRecordTemp();
                                temp.setExpenseAmount((float)(amount/100.00));
                                temp.setMerchantEncode(pos.getMerchantCode());
                                temp.setPosCode(pos.getPosCode());
                                temp.setRechargeablecardCode(card.getRechargeableCardNum());
                                temp.setUpdateTime(new Date());
                                temp.setExpensiveStatus(0);
                                temp.setSerialNumber(generateSerialNum());
                                rechargeCardTradeService.addTempExpensive(temp);
                                String serialNum=temp.getSerialNumber();
                                resp.setValue(37,serialNum , IsoType.ALPHA, 12);
                                float money=card.getRechargeableCardAccountTotal()*100-amount;
                                String balance=wrapBalance(Math.round(money));
                                resp.setValue(54, balance, IsoType.LLVAR, 0);
                                resp.setValue(39,Constants.ResponeCode.approval.value, IsoType.ALPHA, 2);
                            }
                        }else{
                            resp.setValue(39, Constants.ResponeCode.incorrectPin.value, IsoType.ALPHA, 2);
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            resp.setValue(39, Constants.ResponeCode.timeOut.value, IsoType.ALPHA, 2);
        }finally{
            if(card!=null){
                AccountLock.getInstance().remove(card.getRechargeableCardNum());
            }
            if(qrCode!=null){
                AccountLock.getInstance().remove(qrCode);
            }
        }
	}
    /* (non-Javadoc)
     * Description: <br/> 
     *
     * @param req
     * @param macKey
     * @return 
     * @see com.bcinfo.iccard.busi.AbstractBusinessHandler#authenticate(com.solab.iso8583.IsoMessage, java.lang.String)
     */
    @Override
    protected boolean authenticate(IsoMessage req, String macKey)
    {
        // TODO Auto-generated method stub
        return true;
    }
}
